//
//  Api.swift
//  JiaoZiTaxi
//
//  Created by Hu Gang on 2022/9/18.
//

import Alamofire
import Foundation
import Logging

typealias HTTPCode = Int
typealias HTTPCodes = Range<HTTPCode>

extension HTTPCodes {
   static let success = 200 ..< 300
}

enum ApiErrors: Swift.Error {
   case invalidURL
   case httpCode(HTTPCode)
   case unexpectedResponse
   case deserialization
    case invalidResponse
}

enum Api {
   static let logger = Logger(label: "Api")

      // 获取短语信息
   static func getAllShortMessages(completion: @escaping (Result<[DataShortMessage], NetworkError>) -> Void) {
      logger.info("===== API getAllShortMessages =====")

      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/laos_phrase"
      logger.info("url     :\(url)")

      ApiHelper.getRequest(url: url) { r in
         completion(r)
      }
   }

    // 获取所有的城市
   static func getAllCities(completion: @escaping (Result<[DataCity], NetworkError>) -> Void) {
      logger.info("===== API getAllCities =====")

      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/query_laos_init_city"
      logger.info("url     :\(url)")

      ApiHelper.getRequest(url: url) { r in
         completion(r)
      }
   }

   // 获取客服信息
   static func getServiceInfo(completion: @escaping (Result<ServiceInfo, NetworkError>) -> Void) {
      logger.info("===== API getServiceInfo =====")

      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/laos_service_para"
      logger.info("url     :\(url)")

      let jsonData = ""
      ApiHelper.postRequest(url: url, postData: jsonData.data(using: .utf8)!) { r in
         completion(r)
      }
   }

   // 保存乘客个人信息
   static func savePassengerInfo(passengerInfo: Passenger, completion: @escaping (Result<String, NetworkError>) -> Void) {
      logger.info("===== API sagePassengerInfo =====")
      logger.info("passengerInfo:\(passengerInfo)")

      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/saveme4wx_laos?openid=\(passengerInfo.openId)&phone=\(passengerInfo.wechatNo)&laos_phone=\(passengerInfo.laosMobile)&ttype=2&wx=2"
      logger.info("url     :\(url)")

      ApiHelper.getRequest(url: url, completion: { r in
         completion(r)
      })
   }

//   static func listAllCarsAsync() async throws -> [DataListCarsResult] {
    static func listAllCarsAsync() async throws -> [NewCarModel] {
        logger.info("===== API listAllCarsAsync =====")  // wss/jcy/
        
        guard let url = URL(string: "\(Constants.apiBaseUrl)\(Constants.apiCarPath)/laos_all_car") else {
            logger.error("Missing URL")
            throw ApiErrors.invalidURL // 使用错误类型替代fatalError
        }

        logger.info("url     :\(url.absoluteURL)")

        let (data, response) = try await URLSession.shared.data(from: url)
        
        // 打印原始数据
        if let string = String(data: data, encoding: .utf8) {
            print("原始数据（字符串形式）：\n\(string)")
        } else {
            print("数据无法转换为 UTF-8 字符串（可能是二进制数据）")
        }
        
        // 安全的HTTP响应验证
        guard let httpResponse = response as? HTTPURLResponse else {
            throw ApiErrors.invalidResponse
        }
        
        guard httpResponse.statusCode == 200 else {
            throw ApiErrors.httpCode(httpResponse.statusCode)
        }
        
        // 正确的JSON解析方式
        do {
            return try JSONDecoder().decode([NewCarModel].self, from: data)
        } catch {
            logger.error("JSON解析错误: \(error)")
            throw ApiErrors.deserialization
        }
    }

//   static func listAllCars(completion: @escaping (Result<[DataListCarsResult], NetworkError>) -> Void) {
    static func listAllCars(completion: @escaping (Result<[NewCarModel], NetworkError>) -> Void) {
      logger.info("===== API listAllCars =====")

      let url = "\(Constants.apiBaseUrl)\(Constants.apiCarPath)/laos_all_car"
      logger.info("url     :\(url)")

      let jsonData = ""
      ApiHelper.postRequest(url: url, postData: jsonData.data(using: .utf8)!) { r in
         completion(r)
      }
   }

   static func login(account: String, password: String, completion: @escaping (Result<String, NetworkError>) -> Void) {
      logger.info("===== API login =====")
      logger.info("account :\(account)")
      logger.info("password:\(password)")

      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/laos_car_query_account_password?account=\(account)&password=\(password)"
      logger.info("url     :\(url)")

      print(url)
      let jsonData = ""
      ApiHelper.postRequest(url: url, postData: jsonData.data(using: .utf8)!) { r in
         completion(r)
      }
   }

   // 中心化叫车
   static func callCars(callInfo: DataCall, completion: @escaping (Result<DataCallResult, NetworkError>) -> Void) {
      logger.info("===== API callCars =====")
       
       print("callCars 坐标: lat:\(callInfo.lat)  lon:\(callInfo.lon)")
      let url = "\(Constants.apiBaseUrl)\(Constants.apiCarPath)/callcarAsyncServlet?\(callInfo.toUrlParams())"
//       let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/laos_fabulinghuo?\(callInfo.toUrlParams())"
      logger.info("url     :\(url)")
      logger.info("data:\(callInfo)")

      ApiHelper.getRequest(url: url) { r in
         completion(r)
      }
   }

   // 指定叫车
   static func callSpecCar(ownderId: String, callInfo: DataCall, completion: @escaping (Result<DataCallResult, NetworkError>) -> Void) {
      logger.info("===== API spec call car =====")
      var callData = callInfo
      callData.receiverJSON = "[{\"peopleId\":\"\(ownderId)\"}]"
      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/laos_fabulinghuo?\(callData.toUrlParams())"
      logger.info("url     :\(url)")
      logger.info("data:\(callInfo)")

      ApiHelper.getRequest(url: url) { r in
         completion(r)
      }
   }

   // 获取未完成的订单
   static func loadOrder(openId: String, orderId: String, completion: @escaping (Result<String, NetworkError>) -> Void) {
      logger.info("===== API loadOrder =====")
      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/query_car_order_status_for_ios?openid=\(openId)&detection_id=\(orderId)"
      logger.info("url     :\(url)")
      ApiHelper.getRequest(url: url) { r in
         completion(r)
      }
   }

   // 取订单结束总结
   static func loadOrderSummary(openId: String, detectionId: String, completion: @escaping (Result<DataOrderSummaryResult, NetworkError>) -> Void) {
      logger.info("===== API loadOrderSummary =====")
      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/query_order_by_detection_id?detection_id=\(detectionId)&openid=\(openId)"
      logger.info("url     :\(url)")
      ApiHelper.getRequest(url: url) { r in
         completion(r)
      }
   }

   // 上传图片
   static func uploadImage(image: ImageInfo, completion: @escaping (Result<UploadImageResult, NetworkError>) -> Void) {
      logger.info("===== API upload image =====")
      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/uploadPhotos"
      logger.info("url     :\(url)")
      ApiHelper.uploadImage(url: url, image: image) { r in
         completion(r)
      }
   }

   // 上传图片
   static func uploadMp3(mp3Filename: String, completion: @escaping (Result<UploadImageResult, NetworkError>) -> Void) {
      logger.info("===== API upload mp3 =====")
      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/uploadPhotos"
      logger.info("url     :\(url)")
      ApiHelper.uploadMp3(url: url, mp3Filename: mp3Filename) { r in
         completion(r)
      }
   }

   // 更新用户设备的deviceToken和language
   static func updateToken(openId: String, token: String, completion: @escaping (Result<DataDeviceTokenUpdateResult, NetworkError>) -> Void) {
      logger.info("===== API updateToken =====")
      var url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/UpdateAPNToken?ttype=2&token=\(token)&openid=\(openId)&language=\(ViewModel.shared.language.toString())"

      #if DEBUG
         url = "\(url)&env=test"
      #endif
      
      logger.info("url     :\(url)")
      ApiHelper.getRequest(url: url) { r in
         completion(r)
      }
   }

   // 读取未收到的Message
   static func listUnreadMessages(openId: String, completion: @escaping (Result<[DataUnsentMessage], NetworkError>) -> Void) {
      logger.info("===== API listUnreadMessages =====")
      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/mytalkmessage?openid=\(openId)"
      logger.info("url     :\(url)")
      ApiHelper.getRequest(url: url) { r in
         completion(r)
      }
   }

   // 读取未收到的Message V2
   static func listUnreadMessagesV2(openId: String, detectionId: String, completion: @escaping (Result<[DataUnsentMessage], NetworkError>) -> Void) {
      logger.info("===== API listUnreadMessages =====")
      let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/queryOfflineMessageOfDetection?openid=\(openId)&detectionId=\(detectionId)"
      logger.info("url     :\(url)")
      ApiHelper.getRequest(url: url) { r in
         completion(r)
      }
   }
    
    // 保存地址
    static func saveAddress(aId: String, openId: String, name: String, laosPhone: String, phone: String, lat: String, lon: String, type: String, completion: @escaping (Result<String, NetworkError>) -> Void) {
        let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/saveMyOverlay?id=\(aId)&openid=\(openId)&name=\(name)&laos_phone=\(laosPhone)&phone=\(phone)&latitude=\(lat)&longitude=\(lon)&type=\(type)&lang=\(ViewModel.shared.language.toString())&status=1&picture=&intro="
        let encodedString: String = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
        logger.info("url     :\(url)")

        print(url)
        let jsonData = ""
        ApiHelper.postRequest(url: encodedString, postData: jsonData.data(using: .utf8)!) { r in
           completion(r)
        }
    }
    
    // 删除私有地址
    static func deleteAddress(aId: String, openId: String, completion: @escaping (Result<String, NetworkError>) -> Void) {
        let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/delete_laos_store_apply?id=\(aId)&openid=\(openId)"
        logger.info("url     :\(url)")

        print(url)
        ApiHelper.getRequest(url: url) { r in
           completion(r)
        }
    }

    // 获取地址列表
    static func getAddressList(openId: String, type: String, name: String , completion: @escaping (Result<[AddressModel], NetworkError>) -> Void) {
        logger.info("===== API getAddressList =====")
        let url = "\(Constants.apiBaseUrl)\(Constants.apiCarPath)/googlePlace?openid=\(openId)&type=\(type)&name=\(name)&lang=\(ViewModel.shared.language.toString())&category_code"
        logger.info("url     :\(url)")
        ApiHelper.getRequest(url: url) { r in
           completion(r)
        }
    }
    
    // 获取行车轨迹
    static func getCarPath(openId: String, startLat: String, startLon: String, endLat: String, endLon: String, completion: @escaping (Result<[PathCoordinate], NetworkError>) -> Void) {
        logger.info("===== API getCarPath ===== openId :\(openId)latitude:\(endLat)  longitude:\(endLon)")
        let url = "\(Constants.apiBaseUrl)\(Constants.apiCarPath)/googleRoute?openid=\(openId)&lat1=\(startLat)&lon1=\(startLon)&lat2=\(endLat)&lon2=\(endLon)"
        logger.info("url     :\(url)")

        print(url)
        ApiHelper.getRequest(url: url) { r in
           completion(r)
        }
    }
    // 通过经纬度查询地址
    static func googleNearbyPlaces(openId: String, latitude: String, longitude: String,  completion: @escaping (Result<[AddressModel], NetworkError>) -> Void) {
//        if openId.isEmpty{
//            logger.info("===== openId 为空 ===== ")
//            return
//        }
        logger.info("===== API googleNearbyPlaces ===== openId :\(openId)latitude:\(latitude)  longitude:\(longitude)")
        let url = "\(Constants.apiBaseUrl)\(Constants.apiCarPath)/googleNearbyPlaces?openid=\(openId)&latitude=\(latitude)&longitude=\(longitude)&lang=\(ViewModel.shared.language.toString())&rankby=distance"
        logger.info("url     :\(url)")
        ApiHelper.getRequest(url: url) { r in
           completion(r)
        }
    }
    //查询订单
    static func getOrderList(openId: String ,completion:@escaping(Result<[OrderModel],NetworkError>) -> Void) {
        logger.info("===== API getOrderList =====")

        let url = "\(Constants.apiBaseUrl)\(Constants.apiBasePath)/query_order_by_customer_openid?openid=\(openId)&order_type=1"
        logger.info("url     :\(url)")

        ApiHelper.getRequest(url: url) { r in
           completion(r)
        }
    }
    
}
